/* 代码位置: https://zh.cppreference.com/w/cpp/thread/counting_semaphore
*/

#include <chrono>
#include <iostream>
#include <semaphore>
#include <thread>
#include <chrono>

// 全局二元信号量实例
// 设置对象计数为零
// 对象处于未被发信状态
std::binary_semaphore
    smphSignalMainToThread{0},
    smphSignalThreadToMain{0};

void ThreadProc()
{
    // 通过尝试减少信号量的计数等待来自主程序的信号
    smphSignalMainToThread.acquire();

    // 此调用阻塞直至信号量的计数被从主程序增加

    std::cout << "[线程] 21 获得信号" << std::endl; // 回应消息

    // 等待 3 秒以模仿某种线程正在进行的工作
    std::this_thread::sleep_for(std::chrono::seconds(3));


    std::cout << "[线程] 22 发送信号\n"; // 消息

    // 对主程序回复发信
    smphSignalThreadToMain.release();
}

int main()
{
    // 创建某个工作线程
    std::thread thrWorker(ThreadProc);

    std::cout << "[主] 11 发送信号\n"; // 消息

    // 通过增加信号量的计数对工作线程发信以开始工作
    smphSignalMainToThread.release();

    // 通过试图减少信号量的计数等待直至工作线程完成工作
    smphSignalThreadToMain.acquire();

    std::cout << "[主] 12 获得信号\n"; // 回应消息
    thrWorker.join();
}

/*
[主] 11 发送信号
[线程] 21 获得信号
[线程] 22 发送信号
[主] 12 获得信号

 */